/*
 * OptionsTabbedPaneUI.java
 * 
 *  created: 2009-04-29
 *  charset: UTF-8
 *  license: MIT (X11) (See LICENSE file for full license)
 */

package cz.mp.k3bg.gui.plaf;

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicTabbedPaneUI;

/**
 * Třída {@code OptionsTabbedPaneUI} kreslí {@linkplain JTabbedPane}
 * ve stylu známého okna konfigurace v prohlížečích Mozilla Firefox.
 * <p>
 * Použití, např:
 * <tt><pre>
 * OptionsTabbedPaneUI optsTabPaneUI = new OptionsTabbedPaneUI();
 * myTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
 * myTabbedPane.setUI(optsTabPaneUI);
 * </pre></tt>
 * 
 * @author Martin Pokorný
 * @version 0.1
 */
public class OptionsTabbedPaneUI extends BasicTabbedPaneUI {

    /** Barva pozadí panelu se záložkami. */
    private Color background;

    private Color dark;

    /** Barva vybrané záložky. */
    private Color selected;

    /** Barva textu. */
    private Color text;


    private static final int LEFTRIGHT_MARGIN = 12;
    private static final int TOPBOTTOM_MARGIN = 6;


    // Vymaluje vybranou záložku.
    @Override
	protected void paintTabBorder(Graphics g, int tabPlacement,
            int tabIndex, int x, int y, int w, int h, boolean isSelected) {

        g.setColor(background);
        g.fillRect(x, y, w, h);

        if (isSelected) {
            g.setColor(selected);
            g.fillRect(x, y, w, h);
        }        
    }

    // Vymaluje fokus. V této implementaci se fokus záměrně nemaluje.
    @Override
	protected void paintFocusIndicator(Graphics g, int tabPlacement,
            Rectangle[] rects, int tabIndex,
            Rectangle iconRect, Rectangle textRect, boolean isSelected)	{
		// Do nothing
	}


    // Vymaluje pozadí panelu se záložkami
    @Override
    protected void paintTabArea(Graphics g, int tabPlacement,
            int selectedIndex) {

		g.setColor(background);
        g.fillRect(0, 0, tabPane.getBounds().width, tabPane.getBounds().height);

		super.paintTabArea(g, tabPlacement, selectedIndex);
    }


    // Vymaluje text. V této implementaci je text vyhlazován
    @Override
    protected void paintText(Graphics g, int tabPlacement, Font font, 
            FontMetrics metrics, int tabIndex, String title,
            Rectangle textRect, boolean isSelected) {

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(text);
        g2d.drawString(title, textRect.x, textRect.y + metrics.getAscent());
    }


    // Nastavení správce rozložení.
    // V této implementaci se ikona maluje nad textem.
    // viz super.layoutLabel(...)
    @Override
    protected void layoutLabel(int tabPlacement, FontMetrics metrics,
            int tabIndex, String title, Icon icon,
            Rectangle tabRect, Rectangle iconRect, Rectangle textRect,
            boolean isSelected) {

        textRect.x = textRect.y = iconRect.x = iconRect.y = 0;
        
        SwingUtilities.layoutCompoundLabel((JComponent) tabPane,
                metrics, title, icon,
                SwingUtilities.CENTER,
                SwingUtilities.CENTER,
                SwingUtilities.BOTTOM, // text pod ikonou = ikona nad textem
                SwingUtilities.CENTER,
                tabRect,
                iconRect,
                textRect,
                textIconGap);

        int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
        int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
        iconRect.x += xNudge;
        iconRect.y += yNudge;
        textRect.x += xNudge;
        textRect.y += yNudge;
    }


    // Výpočet výšky záložky.
    // viz super.calculateTabHeight(...)
    @Override
    protected int calculateTabHeight(int tabPlacement, int tabIndex, 
            int fontHeight) {

        int height = 0;
        Component c = tabPane.getTabComponentAt(tabIndex);
        if (c != null) {
            height = c.getPreferredSize().height;
        }
        else {
            height += fontHeight;
            Icon icon = getIconForTab(tabIndex);

            if (icon != null) {
                // změna z height = Math.max(height, icon.getIconHeight());
                // na      height += Math.max(height, icon.getIconHeight());
                height += Math.max(height, icon.getIconHeight());
            }
        }
        Insets tabIns = getTabInsets(tabPlacement, tabIndex);
        height += tabIns.top + tabIns.bottom
                + textIconGap
                //+ tabAreaInsets.top + tabAreaInsets.bottom
//                + 6
                + 2 * TOPBOTTOM_MARGIN
                ;
        return height;
    }

    // Výpočet výšky záložky.
    // viz super.calculateTabWidth(...)
    @Override
    protected int calculateTabWidth(int tabPlacement, int tabIndex, 
            FontMetrics metrics) {
        
        Insets tabIns = getTabInsets(tabPlacement, tabIndex);
//        int width = tabIns.left + tabIns.right + 12;
        int width = tabIns.left + tabIns.right + 2 * LEFTRIGHT_MARGIN;
        int iconWidth = 0;
        int textWidth = 0;
        Component tabComponent = tabPane.getTabComponentAt(tabIndex);
        if (tabComponent != null) {
            width += tabComponent.getPreferredSize().width;
        } else {
            Icon icon = getIconForTab(tabIndex);
            if (icon != null) {
                iconWidth = icon.getIconWidth();
            }
            String title = tabPane.getTitleAt(tabIndex);
            textWidth = SwingUtilities.computeStringWidth(metrics, title);
        }
        return Math.max(iconWidth, textWidth) + width;
    }


    // Vymaluje vrchní okraj panelu pod záložkami.
    @Override
    protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
            int selectedIndex, int x, int y, int w, int h) {

        if (tabPlacement == TOP) {
            g.setColor(background);
            g.drawLine(x, y+1, x+w, y+1);
            g.setColor(dark);
            g.drawLine(x, y, x+w, y);
        }
    }


    // Vymaluje spodní okraj panelu pod záložkami.
    @Override
    protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
            int selectedIndex, int x, int y, int w, int h) {

        if (tabPlacement == BOTTOM) {
            g.setColor(background);
            g.drawLine(x, y+h-2, x+w, y+h-2);
            g.setColor(dark);
            g.drawLine(x, y+h-1, x+w, y+h-1);
        }
    }


    // Vymaluje levý okraj panelu pod záložkami.
    @Override
    protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
            int selectedIndex, int x, int y, int w, int h) {

        if (tabPlacement == LEFT) {
            g.setColor(background);
            g.drawLine(x+1, y, x+1, y+h);
            g.setColor(dark);
            g.drawLine(x, y, x, y+h);
        }
    }


    // Vymaluje pravý okraj panelu pod záložkami.
    @Override
    protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
            int selectedIndex, int x, int y, int w, int h) {

        if (tabPlacement == RIGHT) {
            g.setColor(background);
            g.drawLine(x+w-2, y, x+w-2, y+h);
            g.setColor(dark);
            g.drawLine(x+w-1, y, x+w-1, y+h);
        }
    }


    // Vymaluje kompletní okraj panelu pod záložkami.
    // viz super.paintContentBorder(...)
    @Override
    protected void paintContentBorder(Graphics g, int tabPlacement,
            int selectedIndex) {

        Insets insets = tabPane.getInsets();

        int x = insets.left;
        int y = insets.top;
        int w = tabPane.getWidth() - insets.right - insets.left;
        int h = tabPane.getHeight() - insets.top - insets.bottom;

        if (tabPlacement == TOP) {
              y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
              h -= (y - insets.top);
        }
        else if (tabPlacement == BOTTOM) {
              h -= calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
        }
        else if (tabPlacement == LEFT) {
              x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
              w -= (x - insets.left);
        }
        else if (tabPlacement == RIGHT) {
              w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
        }

        paintContentBorderTopEdge(g, tabPlacement, selectedIndex,
                x, y, w, h);
        paintContentBorderLeftEdge(g, tabPlacement, selectedIndex,
                x, y, w, h);
        paintContentBorderBottomEdge(g, tabPlacement, selectedIndex,
                x, y, w, h);
        paintContentBorderRightEdge(g, tabPlacement, selectedIndex,
                x, y, w, h);
    }


    // Získá hodnotu posunutí textu na svislé ose ve vybrané záložce
    @Override
	protected int getTabLabelShiftY(int tabPlacement, int tabIndex, 
            boolean isSelected) {
        return 0;
	}


    // Získá hodnotu posunutí textu na vodorovné ose ve vybrané záložce
    @Override
    protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
            boolean isSelected) {
        return 0;
    }



    @Override
	protected void installDefaults()
	{
		super.installDefaults();
        selectedTabPadInsets = new Insets(0, 0, 0, 0);
        tabInsets = selectedTabPadInsets;
        textIconGap = 2;

        tabAreaInsets.left = 0 + tabInsets.left;
        tabAreaInsets.top = 0 + tabInsets.top;
        tabAreaInsets.right = 0 + tabInsets.right;
        tabAreaInsets.bottom = 0 + tabInsets.bottom;

        // pozn.  barvy nejsou úplně správně... v některých LaF (tmavých) nevypadá moc dobře...
//        selected = new Color(180,200,255);
        selected = new Color(184,207,229);

        background = definedOrDefault(
                UIManager.getColor("TabbedPane.highlight"), Color.WHITE);

        dark = definedOrDefault(
                UIManager.getColor("TabbedPane.shadow"), Color.DARK_GRAY);

        text = definedOrDefault(
                UIManager.getColor("Label.foreground"), Color.BLACK);
	}

    /**
     *
     * @param defined
     * @param defaultColor
     * @return
     */
    private Color definedOrDefault(Color defined, Color defaultColor) {
        if (defined != null) {
            return defined;
        }
        else {
            return defaultColor;
        }
    }


} // OptionsTabbedPaneUI
